import { Checkbox } from 'ant-design-vue'
import type { PropType } from 'vue'

export default defineComponent({
	props: {
		data: {
			type: Array as PropType<any>
		}
	},
	setup(props) {
		const handleExpandBtnClick = node => {
			node.expand = !node.expand
		}

		function getParent(node) {
			let result: any = null
			if (node.pId === null) return null
			function dp(list) {
				for (const item of list) {
					if (item.id === node.pId) {
						result = item
						return
					}
					if (item?.children?.length) {
						dp(item.children)
					}
				}
			}
			dp(props.data)
			return result
		}

		function checkdAll(checked, node) {
			node.checked = checked
			node.indeterminate = false
			if (node?.children?.length) {
				node.children.forEach(child => {
					checkdAll(checked, child)
				})
			}
		}

		// 对父级进行反选
		function checkIndeterminate(node) {
			let root: any = getParent(node)
			if (!root) return
			// 向上遍历父级节点
			while (root) {
				if (root?.children?.length) {
					// 获取当前循环节点已选择的子节点个数
					const checkedChildNodes = root?.children.filter(item => item.checked)

					// 如果没有一个子节点被选中，那么当前节点为不勾选
					if (checkedChildNodes.length === 0) {
						root.checked = false
						root.indeterminate = false
					} else if (checkedChildNodes.length < root?.children.length) {
						// 如果有未勾选的子节点，退出循环，因为从该节点开始以及该节点的所有父级节点都是半状态
						root.indeterminate = true
						root.checked = false
						break
					} else {
						// 到这里说明所有子节点都是选中状态，设置该节点为选中
						root.indeterminate = false
						root.checked = true
					}
				}
				root = getParent(root)
			}
		}

		const handleNodeCheck = (e, node) => {
			const checked = e.target.checked

			// 对子级进行全选
			checkdAll(checked, node)

			checkIndeterminate(node)
		}

		const renderNode = list => {
			return list.map(node => {
				return (
					<div
						key={node.id}
						class="ml-20"
					>
						<div class="flex">
							<div
								onClick={() => handleExpandBtnClick(node)}
								class="cursor-pointer mr-5 w-10 h-20"
							>
								{node?.children?.length && !node?.expand ? <span>+</span> : null}
								{node?.children?.length && node?.expand ? <span>-</span> : null}
							</div>
							<div class="mr-5">
								<Checkbox
									checked={!!node.checked}
									indeterminate={!!node.indeterminate}
									onChange={e => handleNodeCheck(e, node)}
								/>
							</div>
							<div class="node-title">{node.label}</div>
						</div>
						{node.children?.length && node.expand ? renderNode(node.children) : null}
					</div>
				)
			})
		}

		return () => {
			return <div class="node-warp">{props.data?.length ? renderNode(props.data) : null}</div>
		}
	}
})
